package genetic;

import processing.core.PApplet;
import processing.core.PVector;

// DNA is an array of vectors

public class DNA extends PApplet {

	// The genetic sequence
	char[] dna;

	// Constructor (makes a random DNA)
	public DNA(int num) {
		dna = new char[num];
		for (int i = 0; i < dna.length; i++) {
			dna[i] = (char) random(32, 128); // Pick from range of chars
		}
	}

	// Constructor #2, creates the instance based on an existing character array
	DNA(char[] newdna) {
		dna = (char[]) newdna.clone();
	}

	// Converts character array to a String
	String getString() {
		return new String(dna);
	}

	// Fitness function (returns floating point % of "correct" characters)
	float fitness(String target) {
		int score = 0;
		for (int i = 0; i < dna.length; i++) {
			if (dna[i] == target.charAt(i)) {
				score++;
			}
		}
		float fitness = (float) score / (float) target.length();
		return fitness;
	}

	// Returns one element from char array
	char getDNA(int index) {
		return dna[index];
	}

	// Crossover
	public DNA mate(DNA partner) {
		// A new child
		char[] child = new char[dna.length];
		int crossover = (int) (random(dna.length)); // Pick a midpoint
		// Half from one, half from the other
		for (int i = 0; i < dna.length; i++) {
			if (i > crossover)
				child[i] = dna[i];
			else
				child[i] = partner.getDNA(i);
		}
		// make a new DNA object
		DNA newdna = new DNA(child);
		return newdna;
	}

	// Based on a mutation probability, picks a new random character
	public void mutate(float m) {
		for (int i = 0; i < dna.length; i++) {
			if (random(1) < m) {
				dna[i] = (char) random(32, 128);
			}
		}
	}
}
//
// /**
// *
// */
// private static final long serialVersionUID = 1L;
// // The genetic sequence
// PVector[] dna;
//
// // Constructor (makes a DNA of random Vectors)
// public DNA(int num) {
// dna = new PVector[num];
// for (int i = 0; i < dna.length; i++) {
// dna[i] = new PVector(random(-1, 1), random(-1, 1));
// dna[i].normalize();
// }
// }
//
// // Constructor #2, creates the instance based on an existing array
// DNA(PVector[] newdna) {
// // dna = (PVector []) newdna.clone(); //not working as an applet?
// dna = newdna;
// }
//
// // returns one element from char array
// PVector getGene(int index) {
// // just doing some error handling
// if (index < dna.length)
// return dna[index].get();
// else
// return new PVector(0, 0);
// }
//
// // **CROSSOVER***//
// // creates new DNA sequence from two (this & and a partner)
// public DNA mate(DNA partner) {
// PVector[] child = new PVector[dna.length];
// // *pick a midpoint*//
// int crossover = (int) (random(dna.length));
// // *take "half" from one and "half" from the other*//
// for (int i = 0; i < dna.length; i++) {
// if (i > crossover)
// child[i] = getGene(i);
// else
// child[i] = partner.getGene(i);
// }
//
// DNA newdna = new DNA(child);
// return newdna;
// }
//
// // based on a mutation probability, picks a new random Vector
// public void mutate(float m) {
// for (int i = 0; i < dna.length; i++) {
// if (random(1) < m) {
// dna[i] = new PVector(random(-1, 1), random(-1, 1));
// dna[i].normalize();
// }
// }
// }
